#include "../Base.h"



EXTERN_C NTSTATUS
PsReferenceProcessFilePointer(
	IN PEPROCESS Process,
	OUT PVOID* OutFileObject
);
EXTERN_C
NTSTATUS
ObQueryNameString(
	__in PVOID Object,
	__out_bcount(Length) POBJECT_NAME_INFORMATION ObjectNameInfo,
	__in ULONG Length,
	__out PULONG ReturnLength
);
ULONG GetImageNameOffset() {

	UNICODE_STRING uName = { 0 };
	RtlInitUnicodeString(&uName, L"PsGetProcessImageFileName");
	PUCHAR funAddress = (PUCHAR)MmGetSystemRoutineAddress(&uName);
	ULONG offset = *(PULONG)(funAddress + 0x3);
	return offset;
}


ULONG GetProcessFileObjectOffset()
{
	RTL_OSVERSIONINFOW version = { 0 };
	RtlGetVersion(&version);
	if (version.dwMajorVersion == 10)
	{
		if (version.dwBuildNumber != 10240)
		{
			UNICODE_STRING uni = { 0 };

			RtlInitUnicodeString(&uni, L"PsGetProcessImageFileName");
			PUCHAR p = (PUCHAR)MmGetSystemRoutineAddress(&uni);
			ULONG offset = *(PULONG)(p + 3);
			if (offset)
			{
				offset -= 8;
			}
			return offset;
		}
	}

	return 0;
}

ULONG GetPebOffset() {
	UNICODE_STRING uName = { 0 };
	RtlInitUnicodeString(&uName, L"PsGetProcessPeb");
	PUCHAR funAddress = (PUCHAR)MmGetSystemRoutineAddress(&uName);
	ULONG offset = *(PULONG)(funAddress + 0x3);
	return offset;
}



VOID ResetProcessImageName(PEPROCESS fakeProcess, PEPROCESS srcProcess)
{
	PCHAR imageName = PsGetProcessImageFileName(fakeProcess);

	PCHAR targetName = PsGetProcessImageFileName(srcProcess);

	memcpy(imageName, targetName, 15);

}

ULONG GetSeLocateProcessImageNameOffset() {
	ULONG pebOffset = GetPebOffset();
	ULONG seOffset = 0;
	RTL_OSVERSIONINFOW version = { 0 };
	RtlGetVersion(&version);
	if (IsWin7()) {
		seOffset = pebOffset + 0x58;
	}
	else if (version.dwBuildNumber > 7601 && version.dwBuildNumber < 10240) {
		seOffset = pebOffset + 0x68;
	}
	else {
		seOffset = pebOffset + 0x70;
	}

	return seOffset;

}

NTSTATUS ResetProcessImageFileName(PEPROCESS fakeProcess,PEPROCESS srcProcess) {
	PUNICODE_STRING pUSrcName = NULL;
	NTSTATUS status = SeLocateProcessImageName(fakeProcess, &pUSrcName);
	if (!NT_SUCCESS(status)) {
		return status;
	}
	status = SeLocateProcessImageName(fakeProcess, &pUSrcName);



	ULONG seOffset = GetSeLocateProcessImageNameOffset();
	POBJECT_NAME_INFORMATION imageNameInformation = (POBJECT_NAME_INFORMATION) * (PULONG64)((PUCHAR)fakeProcess + seOffset);
	if (pUSrcName->Length <= imageNameInformation->Name.Length) {
		memset(imageNameInformation->Name.Buffer, 0, imageNameInformation->Name.Length);
		memcpy(imageNameInformation->Name.Buffer, pUSrcName->Buffer,pUSrcName->Length);
		imageNameInformation->Name.Length = pUSrcName->Length;
		imageNameInformation->Name.MaximumLength = pUSrcName->MaximumLength;
	}
	else {
		//申请一块内存
		ULONG size = imageNameInformation->Name.MaximumLength + sizeof(UNICODE_STRING);
		PUNICODE_STRING uName = (PUNICODE_STRING)ExAllocatePoolWithTag(NonPagedPool, size, 'yang');
		uName->MaximumLength = imageNameInformation->Name.MaximumLength;
		uName->Length = imageNameInformation->Name.Length;
		memcpy(uName->Buffer, imageNameInformation->Name.Buffer, imageNameInformation->Name.Length);
		*(PULONG64)((PUCHAR)fakeProcess + seOffset) = (ULONG64)uName;
	}


	ExFreePool(pUSrcName);
	
	return status;
}



NTSTATUS ResetProcessObject(PEPROCESS fakeProcess,PEPROCESS srcProcess) {
	PFILE_OBJECT fakeFileObj = NULL;
	PFILE_OBJECT srcFileObJ = NULL;
	

	NTSTATUS status = PsReferenceProcessFilePointer(fakeProcess, (PVOID*)&fakeFileObj);
	
	if (!NT_SUCCESS(status)) {
		return status;
	}
	status = PsReferenceProcessFilePointer(srcProcess, (PVOID*)&srcFileObJ);
	if (!NT_SUCCESS(status)) {
		ObDereferenceObject(fakeFileObj);
		return status;
	}
	ULONG retLen = 0;

	//获取对象名称

	PUNICODE_STRING srcFileName = &srcFileObJ->FileName;
	PUNICODE_STRING fakeFileName = &fakeFileObj->FileName;
	if (fakeFileName->Length >= srcFileName->Length)
	{
		memset(fakeFileName->Buffer, 0, srcFileName->MaximumLength);
		memcpy(fakeFileName->Buffer, srcFileName->Buffer, srcFileName->Length);
		fakeFileName->Length = srcFileName->Length;
		fakeFileName->MaximumLength = srcFileName->MaximumLength;
	}
	else
	{

		SIZE_T size = srcFileName->MaximumLength;

		PWCH fakeName = (PWCH)ExAllocatePool(NonPagedPool, size);

		memcpy(fakeName, srcFileName->Buffer, srcFileName->Length);

		fakeFileName->MaximumLength = srcFileName->MaximumLength;

		fakeFileName->Length = srcFileName->Length;

		fakeFileName->Buffer = fakeName;

		ULONG64 fsContext2 = *(PULONG64)(fakeFileObj->FsContext2);

		if (MmIsAddressValid((PUCHAR)fsContext2))
		{
			PUNICODE_STRING unfsContextName = (PUNICODE_STRING)(fsContext2 + 0x10);

			if (unfsContextName->Length && unfsContextName->MaximumLength)
			{
				unfsContextName->Buffer = fakeName;
				unfsContextName->Length = fakeFileName->Length;
				unfsContextName->MaximumLength = unfsContextName->MaximumLength;
			}
		}
	}
	
	//修改盘符
	fakeFileObj->Vpb = srcFileObJ->Vpb;
	fakeFileObj->DeviceObject = srcFileObJ->DeviceObject;

	ObDereferenceObject(srcFileObJ);

	ObDereferenceObject(fakeFileObj);
}


void ResetProcessFileObjectNameWin10(PEPROCESS fakeProcess, PEPROCESS srcProcess)
{
	RTL_OSVERSIONINFOW version = { 0 };

	RtlGetVersion(&version);

	if (version.dwMajorVersion < 10)
	{
		return;
	}

	ULONG fileOffset = GetProcessFileObjectOffset();

	PFILE_OBJECT fakeFileObj = (PFILE_OBJECT) * (PULONG64)(fileOffset + (PUCHAR)fakeProcess);

	PFILE_OBJECT srcFileObj = (PFILE_OBJECT) * (PULONG64)(fileOffset + (PUCHAR)srcProcess);;

	OBJECT_NAME_INFORMATION srcFileName;



	PUNICODE_STRING usrcName = &srcFileObj->FileName;

	PUNICODE_STRING ufakeName = &fakeFileObj->FileName;

	PWCH fakeName = NULL;

	if (ufakeName->Length >= usrcName->Length)
	{
		memset(ufakeName->Buffer, 0, usrcName->MaximumLength);

		memcpy(ufakeName->Buffer, usrcName->Buffer, usrcName->Length);

		fakeName = ufakeName->Buffer;



	}
	else
	{
		//����һ���ڴ�
		SIZE_T size = usrcName->MaximumLength;

		fakeName = (PWCH)ExAllocatePool(NonPagedPool, size);

		memset(fakeName, 0, size);

		memcpy(fakeName, usrcName->Buffer, usrcName->Length);

		ufakeName->Buffer = fakeName;

	}

	ufakeName->MaximumLength = usrcName->MaximumLength;

	ufakeName->Length = usrcName->Length;

	ULONG64 fsContext2 = *(PULONG64)((PUCHAR)fakeFileObj + 0x20);

	if (MmIsAddressValid((PUCHAR)fsContext2))
	{
		PUNICODE_STRING unfsContextName = (PUNICODE_STRING)(fsContext2 + 0x10);

		if (unfsContextName->Length && unfsContextName->MaximumLength)
		{
			unfsContextName->Buffer = fakeName;
			unfsContextName->Length = ufakeName->Length;
			unfsContextName->MaximumLength = ufakeName->MaximumLength;
		}
	}

	fakeFileObj->DeviceObject = srcFileObj->DeviceObject;
	fakeFileObj->Vpb = srcFileObj->Vpb;


}



PVOID GetTokenUserSidPointer(PVOID token)
{
	RTL_OSVERSIONINFOW version = { 0 };

	RtlGetVersion(&version);

	int offset = 0;

	PVOID result = NULL;

	if (version.dwBuildNumber == 7600 || version.dwBuildNumber == 7601)
	{
		offset = 0x90;
	}
	else
	{
		offset = 0x98;
	}

	if (offset)
	{
		ULONG64 userGs = *(PULONG64)((ULONG64)token + offset);
		if (userGs)
		{
			result = (PVOID)(*(PULONG64)userGs);
		}
	}

	return result;
}

void ResetProcessTokenGroup(PEPROCESS fakeProcess, PEPROCESS srcProcess)
{

	ULONG64 pSystemToken = (ULONG64)PsReferencePrimaryToken(srcProcess);
	ULONG64 MyToken = (ULONG64)PsReferencePrimaryToken(fakeProcess);

	PVOID mvt = GetTokenUserSidPointer((PVOID)MyToken);
	PVOID svt = GetTokenUserSidPointer((PVOID)pSystemToken);
	if (mvt && svt)
	{
		memcpy(mvt, svt, 0x20);
	}

	ObDereferenceObject((PVOID)pSystemToken);
	ObDereferenceObject((PVOID)MyToken);
}

void ResetProcessPeb64Param(PEPROCESS fakeProcess, PEPROCESS srcProcess)
{

	PPEB fakePeb = (PPEB)PsGetProcessPeb(srcProcess);

	PPEB srcPeb = (PPEB)PsGetProcessPeb(fakeProcess);

	if (!srcPeb || !fakePeb) return;

	KAPC_STATE fakeApcState = { 0 };

	KAPC_STATE srcApcState = { 0 };

	UNICODE_STRING ImagePathName = { 0 };
	UNICODE_STRING CommandLine = { 0 };
	UNICODE_STRING WindowTitle = { 0 };

	KeStackAttachProcess(srcProcess, &srcApcState);

	//��ֹ����������R3�ڴ�����
	SIZE_T pro = NULL;
	MmCopyVirtualMemory(srcProcess, srcPeb, srcProcess, srcPeb, 1, UserMode,  &pro);

	MmCopyVirtualMemory(srcProcess, srcPeb->ProcessParameters, srcProcess, srcPeb->ProcessParameters, 1, UserMode, &pro);

	if (srcPeb->ProcessParameters->ImagePathName.Length)
	{
		ImagePathName.Buffer = (PWCH)ExAllocatePool(NonPagedPool, srcPeb->ProcessParameters->ImagePathName.MaximumLength);
		memcpy(ImagePathName.Buffer, srcPeb->ProcessParameters->ImagePathName.Buffer, srcPeb->ProcessParameters->ImagePathName.Length);
		ImagePathName.Length = srcPeb->ProcessParameters->ImagePathName.Length;
		ImagePathName.MaximumLength = srcPeb->ProcessParameters->ImagePathName.MaximumLength;
	}


	if (srcPeb->ProcessParameters->CommandLine.Length)
	{
		CommandLine.Buffer = (PWCH)ExAllocatePool(NonPagedPool, srcPeb->ProcessParameters->CommandLine.MaximumLength);
		memcpy(CommandLine.Buffer, srcPeb->ProcessParameters->CommandLine.Buffer, srcPeb->ProcessParameters->CommandLine.Length);
		CommandLine.Length = srcPeb->ProcessParameters->CommandLine.Length;
		CommandLine.MaximumLength = srcPeb->ProcessParameters->CommandLine.MaximumLength;
	}


	if (srcPeb->ProcessParameters->WindowTitle.Length)
	{
		WindowTitle.Buffer = (PWCH)ExAllocatePool(NonPagedPool, srcPeb->ProcessParameters->WindowTitle.MaximumLength);
		memcpy(WindowTitle.Buffer, srcPeb->ProcessParameters->WindowTitle.Buffer, srcPeb->ProcessParameters->WindowTitle.Length);
		WindowTitle.Length = srcPeb->ProcessParameters->WindowTitle.Length;
		WindowTitle.MaximumLength = srcPeb->ProcessParameters->WindowTitle.MaximumLength;
	}

	KeUnstackDetachProcess(&srcApcState);


	KeStackAttachProcess(fakeProcess, &fakeApcState);

	MmCopyVirtualMemory(fakeProcess, fakePeb, fakeProcess, fakePeb, 1, UserMode, &pro);

	MmCopyVirtualMemory(fakeProcess, fakePeb->ProcessParameters, fakeProcess, fakePeb->ProcessParameters, 1, UserMode, &pro);

	PVOID BaseAddr = NULL;
	SIZE_T size = PAGE_SIZE;
	NTSTATUS status = ZwAllocateVirtualMemory(NtCurrentProcess(), &BaseAddr, 0, &size, MEM_COMMIT, PAGE_READWRITE);
	PUCHAR tempBase = (PUCHAR)BaseAddr;


	if (fakePeb->ProcessParameters->ImagePathName.Length && ImagePathName.Length)
	{
		if (fakePeb->ProcessParameters->ImagePathName.Length >= ImagePathName.Length)
		{
			memset(fakePeb->ProcessParameters->ImagePathName.Buffer, 0, fakePeb->ProcessParameters->ImagePathName.MaximumLength);

			memcpy(fakePeb->ProcessParameters->ImagePathName.Buffer, ImagePathName.Buffer, ImagePathName.Length);

			fakePeb->ProcessParameters->ImagePathName.Length = ImagePathName.Length;
		}
		else
		{
			if (!NT_SUCCESS(status))
			{
				memset(fakePeb->ProcessParameters->ImagePathName.Buffer, 0, fakePeb->ProcessParameters->ImagePathName.MaximumLength);
				fakePeb->ProcessParameters->ImagePathName.Length = 0;
				fakePeb->ProcessParameters->ImagePathName.MaximumLength = 0;
			}
			else
			{
				memcpy(tempBase, ImagePathName.Buffer, ImagePathName.Length);
				fakePeb->ProcessParameters->ImagePathName.Length = ImagePathName.Length;
				fakePeb->ProcessParameters->ImagePathName.MaximumLength = ImagePathName.MaximumLength;
				fakePeb->ProcessParameters->ImagePathName.Buffer = (PWCH)tempBase;
				tempBase += ImagePathName.MaximumLength;
			}
		}
	}


	if (fakePeb->ProcessParameters->CommandLine.Length && CommandLine.Length)
	{
		if (fakePeb->ProcessParameters->CommandLine.Length >= CommandLine.Length)
		{
			memset(fakePeb->ProcessParameters->CommandLine.Buffer, 0, fakePeb->ProcessParameters->CommandLine.MaximumLength);

			memcpy(fakePeb->ProcessParameters->CommandLine.Buffer, CommandLine.Buffer, CommandLine.Length);

			fakePeb->ProcessParameters->CommandLine.Length = CommandLine.Length;
		}
		else
		{
			if (!NT_SUCCESS(status))
			{
				memset(fakePeb->ProcessParameters->CommandLine.Buffer, 0, fakePeb->ProcessParameters->CommandLine.MaximumLength);
				fakePeb->ProcessParameters->CommandLine.Length = 0;
				fakePeb->ProcessParameters->CommandLine.MaximumLength = 0;
			}
			else
			{
				memcpy(tempBase, CommandLine.Buffer, CommandLine.Length);
				fakePeb->ProcessParameters->CommandLine.Length = CommandLine.Length;
				fakePeb->ProcessParameters->CommandLine.MaximumLength = CommandLine.MaximumLength;
				fakePeb->ProcessParameters->CommandLine.Buffer = (PWCH)tempBase;
				tempBase += CommandLine.MaximumLength;
			}
		}
	}


	if (fakePeb->ProcessParameters->WindowTitle.Length && WindowTitle.Length)
	{
		if (fakePeb->ProcessParameters->WindowTitle.Length >= WindowTitle.Length)
		{
			memset(fakePeb->ProcessParameters->WindowTitle.Buffer, 0, fakePeb->ProcessParameters->WindowTitle.MaximumLength);

			memcpy(fakePeb->ProcessParameters->WindowTitle.Buffer, WindowTitle.Buffer, WindowTitle.Length);

			fakePeb->ProcessParameters->WindowTitle.Length = WindowTitle.Length;
		}
		else
		{
			if (!NT_SUCCESS(status))
			{
				memset(fakePeb->ProcessParameters->WindowTitle.Buffer, 0, fakePeb->ProcessParameters->WindowTitle.MaximumLength);
				fakePeb->ProcessParameters->WindowTitle.Length = 0;
				fakePeb->ProcessParameters->WindowTitle.MaximumLength = 0;
			}
			else
			{
				memcpy(tempBase, WindowTitle.Buffer, WindowTitle.Length);
				fakePeb->ProcessParameters->WindowTitle.Length = WindowTitle.Length;
				fakePeb->ProcessParameters->WindowTitle.MaximumLength = WindowTitle.MaximumLength;
				fakePeb->ProcessParameters->WindowTitle.Buffer = (PWCH)tempBase;

			}
		}
	}


	KeUnstackDetachProcess(&fakeApcState);

	if (ImagePathName.Length) ExFreePool(ImagePathName.Buffer);
	if (CommandLine.Length) ExFreePool(CommandLine.Buffer);
	if (WindowTitle.Length) ExFreePool(WindowTitle.Buffer);

}

void ResetProcessPeb64Moudle(PEPROCESS fakeProcess, PEPROCESS srcProcess)
{
	PPEB fakePeb = (PPEB)PsGetProcessPeb(fakeProcess);

	PPEB srcPeb = (PPEB)PsGetProcessPeb(srcProcess);

	if (!srcPeb || !fakePeb) return;

	KAPC_STATE fakeApcState = { 0 };

	KAPC_STATE srcApcState = { 0 };

	UNICODE_STRING FullDllName = { 0 };
	ULONG baseLen = 0;

	KeStackAttachProcess(srcProcess, &srcApcState);

	//��ֹ����������R3�ڴ�����
	SIZE_T pro = NULL;
	MmCopyVirtualMemory(srcProcess, srcPeb, srcProcess, srcPeb, 1, UserMode, &pro);

	MmCopyVirtualMemory(srcProcess, srcPeb->Ldr, srcProcess, srcPeb->Ldr, 1, UserMode, &pro);

	PLDR_DATA_TABLE_ENTRY list = (PLDR_DATA_TABLE_ENTRY)srcPeb->Ldr->InLoadOrderModuleList.Flink;

	if (list->FullDllName.Length)
	{
		FullDllName.Buffer = (PWCH)ExAllocatePool(NonPagedPool, list->FullDllName.MaximumLength);

		memcpy(FullDllName.Buffer, list->FullDllName.Buffer, list->FullDllName.Length);

		FullDllName.Length = list->FullDllName.Length;

		FullDllName.MaximumLength = list->FullDllName.MaximumLength;

		baseLen = (PUCHAR)list->BaseDllName.Buffer - (PUCHAR)list->FullDllName.Buffer;
	}

	KeUnstackDetachProcess(&srcApcState);

	//����Դ����
	KeStackAttachProcess(fakeProcess, &fakeApcState);

	//��ֹ����������R3�ڴ�����
	MmCopyVirtualMemory(fakeProcess, fakePeb, fakeProcess, fakePeb, 1, UserMode, &pro);

	MmCopyVirtualMemory(fakeProcess, fakePeb->Ldr, fakeProcess, fakePeb->Ldr, 1, UserMode, &pro);

	PLDR_DATA_TABLE_ENTRY fakeList = (PLDR_DATA_TABLE_ENTRY)fakePeb->Ldr->InLoadOrderModuleList.Flink;

	if (fakeList->FullDllName.Length >= FullDllName.Length)
	{
		memset(fakeList->FullDllName.Buffer, 0, fakeList->FullDllName.MaximumLength);

		memcpy(fakeList->FullDllName.Buffer, FullDllName.Buffer, FullDllName.Length);

		fakeList->FullDllName.Length = FullDllName.Length;
	}
	else
	{
		PVOID BaseAddr = NULL;

		SIZE_T size = PAGE_SIZE;

		NTSTATUS status = ZwAllocateVirtualMemory(NtCurrentProcess(), &BaseAddr, 0, &size, MEM_COMMIT, PAGE_READWRITE);

		memcpy(BaseAddr, FullDllName.Buffer, FullDllName.Length);

		fakeList->FullDllName.Length = FullDllName.Length;

		fakeList->FullDllName.MaximumLength = FullDllName.MaximumLength;

		fakeList->FullDllName.Buffer = (PWCH)BaseAddr;
	}

	fakeList->BaseDllName.Buffer = (PWCH)(fakeList->FullDllName.Buffer + baseLen);
	fakeList->BaseDllName.Length = fakeList->FullDllName.Length - baseLen;
	fakeList->BaseDllName.MaximumLength = baseLen + 2;

	KeUnstackDetachProcess(&fakeApcState);


	if (FullDllName.Length) ExFreePool(FullDllName.Buffer);
}



void ResetProcessPeb32Param(PEPROCESS fakeProcess)
{

	PPEB32 peb32 = (PPEB32)PsGetProcessWow64Process(fakeProcess);

	if (!peb32) return;

	PPEB fakePeb = (PPEB)PsGetProcessPeb(fakeProcess);


	if (!fakePeb) return;

	KAPC_STATE fakeApcState = { 0 };

	KeStackAttachProcess(fakeProcess, &fakeApcState);

	SIZE_T pro = NULL;
	MmCopyVirtualMemory(fakeProcess, fakePeb, fakeProcess, fakePeb, 1, UserMode, &pro);

	MmCopyVirtualMemory(fakeProcess, fakePeb->ProcessParameters, fakeProcess, fakePeb->ProcessParameters, 1, UserMode, &pro);

	MmCopyVirtualMemory(fakeProcess, peb32, fakeProcess, peb32, 1, UserMode, &pro);

	PRTL_USER_PROCESS_PARAMETERS32 param32 = (PRTL_USER_PROCESS_PARAMETERS32)ULongToPtr(peb32->ProcessParameters);

	MmCopyVirtualMemory(fakeProcess, param32, fakeProcess,
		param32, 1, UserMode, &pro);

	PVOID BaseAddr = NULL;
	SIZE_T size = PAGE_SIZE;
	NTSTATUS status = ZwAllocateVirtualMemory(NtCurrentProcess(), &BaseAddr, 0, &size, MEM_COMMIT, PAGE_READWRITE);
	PUCHAR tempBase = (PUCHAR)BaseAddr;



	if (fakePeb->ProcessParameters->ImagePathName.Length)
	{

		if (param32->ImagePathName.Length >= fakePeb->ProcessParameters->ImagePathName.Length)
		{
			memset((PVOID)param32->ImagePathName.Buffer, 0, param32->ImagePathName.MaximumLength);

			memcpy((PVOID)param32->ImagePathName.Buffer, fakePeb->ProcessParameters->ImagePathName.Buffer, fakePeb->ProcessParameters->ImagePathName.Length);

			param32->ImagePathName.Length = fakePeb->ProcessParameters->ImagePathName.Length;
		}
		else
		{
			if (!NT_SUCCESS(status))
			{
				memset((PVOID)param32->ImagePathName.Buffer, 0, param32->ImagePathName.MaximumLength);
				param32->ImagePathName.Length = 0;
				param32->ImagePathName.MaximumLength = 0;
			}
			else
			{
				memcpy(tempBase, fakePeb->ProcessParameters->ImagePathName.Buffer, fakePeb->ProcessParameters->ImagePathName.Length);
				param32->ImagePathName.Length = fakePeb->ProcessParameters->ImagePathName.Length;
				param32->ImagePathName.MaximumLength = fakePeb->ProcessParameters->ImagePathName.MaximumLength;
				param32->ImagePathName.Buffer = (ULONG)tempBase;
				tempBase += param32->ImagePathName.MaximumLength;
			}
		}
	}


	if (fakePeb->ProcessParameters->CommandLine.Length)
	{
		if (param32->CommandLine.Length >= fakePeb->ProcessParameters->CommandLine.Length)
		{
			memset((PVOID)param32->CommandLine.Buffer, 0, param32->CommandLine.MaximumLength);

			memcpy((PVOID)param32->CommandLine.Buffer, fakePeb->ProcessParameters->CommandLine.Buffer, fakePeb->ProcessParameters->CommandLine.Length);

			param32->CommandLine.Length = fakePeb->ProcessParameters->CommandLine.Length;
		}
		else
		{
			if (!NT_SUCCESS(status))
			{
				memset((PVOID)param32->CommandLine.Buffer, 0, param32->CommandLine.MaximumLength);
				param32->CommandLine.Length = 0;
				param32->CommandLine.MaximumLength = 0;


			}
			else
			{
				memcpy(tempBase, fakePeb->ProcessParameters->CommandLine.Buffer, fakePeb->ProcessParameters->CommandLine.Length);
				param32->CommandLine.Length = fakePeb->ProcessParameters->CommandLine.Length;
				param32->CommandLine.MaximumLength = fakePeb->ProcessParameters->CommandLine.MaximumLength;
				param32->CommandLine.Buffer = (ULONG)tempBase;
				tempBase += param32->CommandLine.MaximumLength;


			}
		}
	}

	if (fakePeb->ProcessParameters->WindowTitle.Length)
	{
		if (param32->WindowTitle.Length >= fakePeb->ProcessParameters->WindowTitle.Length)
		{
			memset((PVOID)param32->WindowTitle.Buffer, 0, param32->WindowTitle.MaximumLength);

			memcpy((PVOID)param32->WindowTitle.Buffer, fakePeb->ProcessParameters->WindowTitle.Buffer, fakePeb->ProcessParameters->WindowTitle.Length);

			param32->WindowTitle.Length = fakePeb->ProcessParameters->WindowTitle.Length;
		}
		else
		{
			if (!NT_SUCCESS(status))
			{
				memset((PVOID)param32->WindowTitle.Buffer, 0, param32->WindowTitle.MaximumLength);
				param32->WindowTitle.Length = 0;
				param32->WindowTitle.MaximumLength = 0;


			}
			else
			{
				memcpy(tempBase, fakePeb->ProcessParameters->WindowTitle.Buffer, fakePeb->ProcessParameters->WindowTitle.Length);
				param32->WindowTitle.Length = fakePeb->ProcessParameters->WindowTitle.Length;
				param32->WindowTitle.MaximumLength = fakePeb->ProcessParameters->WindowTitle.MaximumLength;
				param32->WindowTitle.Buffer = (ULONG)tempBase;
				tempBase += param32->WindowTitle.MaximumLength;


			}
		}
	}
	else
	{
		memset((PVOID)param32->WindowTitle.Buffer, 0, param32->WindowTitle.MaximumLength);
		param32->WindowTitle.Length = 0;
		param32->WindowTitle.MaximumLength = 0;
	}

	KeUnstackDetachProcess(&fakeApcState);



}

void resetProcessPeb32Moudle(PEPROCESS fakeProcess)
{

	PPEB32 peb32 = (PPEB32)PsGetProcessWow64Process(fakeProcess);

	if (!peb32) return;

	PPEB fakePeb = (PPEB)PsGetProcessPeb(fakeProcess);

	if (!fakePeb) return;

	KAPC_STATE fakeApcState = { 0 };


	ULONG baseLen = 0;


	//����Դ����
	KeStackAttachProcess(fakeProcess, &fakeApcState);

	SIZE_T pro = NULL;
	//��ֹ����������R3�ڴ�����
	MmCopyVirtualMemory(fakeProcess, fakePeb, fakeProcess, fakePeb, 1, UserMode, &pro);

	MmCopyVirtualMemory(fakeProcess, fakePeb->Ldr, fakeProcess, fakePeb->Ldr, 1, UserMode, &pro);

	MmCopyVirtualMemory(fakeProcess, peb32, fakeProcess, peb32, 1, UserMode, &pro);

	PPEB_LDR_DATA32 pldr32 = (PPEB_LDR_DATA32)ULongToPtr(peb32->Ldr);

	MmCopyVirtualMemory(fakeProcess, pldr32, fakeProcess, pldr32, 1, UserMode, &pro);


	PLDR_DATA_TABLE_ENTRY fakeList = (PLDR_DATA_TABLE_ENTRY)fakePeb->Ldr->InLoadOrderModuleList.Flink;
	PLDR_DATA_TABLE_ENTRY32 fakeList32 = (PLDR_DATA_TABLE_ENTRY32)ULongToPtr(pldr32->InLoadOrderModuleList.Flink);

	if (fakeList32->FullDllName.Length >= fakeList->FullDllName.Length)
	{
		memset(fakeList32->FullDllName.Buffer, 0, fakeList32->FullDllName.MaximumLength);

		memcpy(fakeList32->FullDllName.Buffer, fakeList->FullDllName.Buffer, fakeList->FullDllName.Length);

		fakeList32->FullDllName.Length = fakeList->FullDllName.Length;
	}
	else
	{
		PVOID BaseAddr = NULL;

		SIZE_T size = PAGE_SIZE;

		NTSTATUS status = ZwAllocateVirtualMemory(NtCurrentProcess(), &BaseAddr, 0, &size, MEM_COMMIT, PAGE_READWRITE);

		memcpy(BaseAddr, fakeList->FullDllName.Buffer, fakeList->FullDllName.Length);

		fakeList32->FullDllName.Length = fakeList->FullDllName.Length;

		fakeList32->FullDllName.MaximumLength = fakeList->FullDllName.MaximumLength;

		fakeList32->FullDllName.Buffer = (PWCH)BaseAddr;
	}

	fakeList32->BaseDllName.Buffer = (PWCH)((PUCHAR)fakeList->FullDllName.Buffer + baseLen);
	fakeList32->BaseDllName.Length = fakeList->FullDllName.Length - baseLen;
	fakeList32->BaseDllName.MaximumLength = baseLen + 2;

	KeUnstackDetachProcess(&fakeApcState);

}




NTSTATUS FakeProcessByPid(PEPROCESS fakeProcess, HANDLE srcPid) {

	PEPROCESS process = NULL;
	NTSTATUS status  =  PsLookupProcessByProcessId(srcPid, &process);
	if (!NT_SUCCESS(status)) {
		return status;
	}

	if (PsGetProcessExitStatus(process) != STATUS_PENDING) {
		return STATUS_THREAD_IS_TERMINATING;
	}

	ResetProcessImageFileName(fakeProcess, process);


}